package com.smart.service.impl;

import com.smart.global.GlobalWord;
import com.smart.pojo.*;
import com.smart.req.OutboundCompleteData;
import com.smart.service.*;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

@Service
public class OutboundProcessServiceImpl implements OutboundProcessService {
    @Autowired
    RepositoryService repositoryService;

    @Autowired
    RuntimeService runtimeService;

    @Autowired
    TaskService taskService;

    @Autowired
    HistoryService historyService;

    @Autowired
    IOutboundBillService outboundBillService;

    @Autowired
    IRoleService roleService;

    @Autowired
    IUserService userService;

    @Autowired
    IDepartmentService departmentService;

    @Autowired
    IProductService productService;

    @Autowired
    private ISalesOrderService salesOrderService;

    @Autowired
    IFinanceService financeService;

    @Autowired
    ISalaryService salaryService;


    @Override
    @Transactional
    public boolean startOutboundProcess(OutboundBill outboundBill) {
        //先保存出库单,初始状态为0审批中
        outboundBill.setStatus(0);
        boolean save = outboundBillService.save(outboundBill);

        if (save) {
            //预处理关联产品库存
            Product product = productService.getById(outboundBill.getProductId());
            product.setNum(product.getNum() - outboundBill.getQuantity());
            productService.updateById(product);

            //更新关联销售单
            SalesOrder salesOrder = salesOrderService.getById(outboundBill.getSalesOrderId());
            salesOrder.setStatus(1);
            salesOrderService.updateById(salesOrder);
        }

        //流程推进变量
        Map<String, Object> map = new HashMap<>();
        //设定请假申请人
        map.put("empId", outboundBill.getUserId());
        //设定生产部长
        User produceMinister = userService.lambdaQuery()
                .eq(User::getRoleId, GlobalWord.PRODUCE_MINISTER_ROLE_ID)
                .one();
        map.put("produceMinisterId", produceMinister.getId());

        //判断是什么角色请假，设定申请级别
        User produceUser = userService.getById(outboundBill.getUserId());
        if (produceUser.getRoleId() != null) {
            //获取角色信息
            Role produceRole = roleService.getById(produceUser.getRoleId());
            //判断是否部长角色
            if (produceRole.getIsLeader() == 1) {
                map.put("isMinister", true);
            } else {
                //部门普通员工角色
                map.put("isMinister", false);
            }
        } else {
            map.put("isMinister", false);
        }

        //构造流程实例关联请假单的唯一标识
        String businessKey = GlobalWord.OUTBOUND_KEY + "." + outboundBill.getId();
        //开启请假流程
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(GlobalWord.OUTBOUND_KEY, businessKey, map);
        return save & !ObjectUtils.isEmpty(processInstance);
    }

    @Override
    @Transactional
    public void complete(OutboundCompleteData outboundCompleteData) {
        //设置流程推进信息
        Map<String, Object> map = new HashMap<>();
        map.put("msg", outboundCompleteData.getSequence());

        //判断是否要更新请假单信息
        if (outboundCompleteData.getOutboundBill() != null) {
            outboundCompleteData.getOutboundBill().setStatus(0);
            outboundBillService.updateById(outboundCompleteData.getOutboundBill());
        }

        //获取当前任务节点
        Task task = taskService.createTaskQuery().taskId(outboundCompleteData.getTaskId()).singleResult();
        //获取businessKey
        ProcessInstance pi = runtimeService.createProcessInstanceQuery()
                .processInstanceId(task.getProcessInstanceId())
                .singleResult();
        String businessKey = pi.getBusinessKey();

        //获取当前流程实例关联的请假单
        OutboundBill bill = outboundBillService.getById(Long.parseLong(businessKey.split("\\.")[1]));

        //设置批注人以及批注信息
        Authentication.setAuthenticatedUserId(outboundCompleteData.getUserId().toString());
        taskService.addComment(task.getId(), task.getProcessInstanceId(), outboundCompleteData.getComment());

        //如果是驳回流程,更新请假单信息
        if (outboundCompleteData.getSequence().equals("驳回")) {
            bill.setStatus(2);
            outboundBillService.updateById(bill);
        }

        //推进流程
        taskService.complete(outboundCompleteData.getTaskId(), map);

        //判断流程是否结束
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                .processInstanceId(task.getProcessInstanceId())
                .singleResult();

        if (processInstance == null) {
            //流程结束，处理请假成功相关信息
            bill.setStatus(1);
            outboundBillService.updateById(bill);

            //关联销售单完成，改变状态
            SalesOrder salesOrder = salesOrderService.getById(bill.getSalesOrderId());
            salesOrder.setStatus(2);
            salesOrderService.updateById(salesOrder);

            //保存销售金额财务记录
            Finance finance = new Finance();
            finance.setType(3);
            finance.setAmount(salesOrder.getTurnover());
            financeService.save(finance);

            //计算关联销售人员的销售提成
            Salary salary = salaryService.getByUserId(salesOrder.getUserId());
            BigDecimal salesAmount = salesOrder.getTurnover().multiply(new BigDecimal("0.05"));
            salary.setSalesAmount(salary.getSalesAmount().add(salesAmount));
            salaryService.updateById(salary);
        }
    }
}
